package com.ebook.server.service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import com.ebook.core.domain.Bookmarker;
import com.ebook.core.domain.ReadPosition;
import com.ebook.core.util.BookmarkerUtil;
import com.ebook.util.ErrorCode;
import com.ebook.util.Status;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

@Service
@Transactional
public class BookmarkService {

	@Resource
	private JdbcTemplate jdbcTemplate;

	@Resource
	private UserService userService;

	/**
	 * 书签同步功能
	 * @param uid
	 * @param json
	 * @param request
	 * @return 成功、失败信息（首选jsp试图，如果找不到找json试图）
	 */
	public ModelAndView bookmarkSync(int uid, String json, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		Gson gson = new Gson();
		List<Bookmarker> list = gson.fromJson(json, new TypeToken<List<Bookmarker>>() {
		}.getType());
		if (!addBookmark(list)) {
			status = Status.REJECTED + ":" + ErrorCode.MARKER_ADD_FAIL;
		}
		//		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 阅读位置同步
	 * @param uid
	 * @param json
	 * @param model
	 * @param request
	 * @return 首选jsp试图，如果找不到找json试图
	 */
	public ModelAndView readPositionSync(int uid, String json, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		Gson gson = new Gson();
		List<ReadPosition> list = gson.fromJson(json, new TypeToken<List<ReadPosition>>() {
		}.getType());
		if (!addReadPosition(list)) {
			status = Status.REJECTED + ":" + ErrorCode.REAKPOSITION_ADD_FAIL;
		}
		//		}		
		modelMap.put("status", status);
		//		modelMap.put("data", readPosition);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 获取所有书签信息
	 * @param uid     用户名Id
	 * @param model
	 * @param request
	 * @return 视图
	*/
	public ModelAndView getBookmark(int uid, int bookid, String json, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		List<Bookmarker> bookmarkerList = null;
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		Gson gson = new Gson();
		List<Bookmarker> list = gson.fromJson(json, new TypeToken<List<Bookmarker>>() {
		}.getType());
		bookmarkerList = getBookmarkByNoMarkerids(uid, bookid, list);
		//		}
		modelMap.put("status", status);
		modelMap.put("bookmarkerList", bookmarkerList);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 根据书签
	 * @param uid
	 * @param markerid
	 * @param model
	 * @param request
	 * @return 成功失败信息
	*/
	public ModelAndView deleteBookmark(int uid, String markerids, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		List<Bookmarker> list = new Gson().fromJson(markerids, new TypeToken<List<Bookmarker>>() {
		}.getType());
		if (!deleteByMarkerids(list)) {
			status = Status.REJECTED + ":" + ErrorCode.MARKER_DELETE_FAIL;
		}
		//		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 获取一本书的阅读位置信息
	 * @param uid
	 * @param bookid
	 * @param model
	 * @param request
	 * @return 获取的信息
	*/
	public ModelAndView getReadPosition(int uid, int bookid, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		List<ReadPosition> readPositionList = null;
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		readPositionList = getReadPositionByBookid(uid, bookid);
		if (readPositionList.size() == 0) {
			status = Status.REJECTED + ":" + ErrorCode.REAKPOSITION_GET_FAIL;
		}
		//		}
		modelMap.put("status", status);
		modelMap.put("readPositionList", readPositionList);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 将书签同步到数据库
	 * 
	 * @param list
	 *            需要同步的信息
	 * @return true：成功
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean addBookmark(final List<Bookmarker> list) {
		String selectSql = "select count(*)as count from bookmarker where markerid=? ";
		System.out.println(selectSql);
		for (Bookmarker b : list) {
			if (jdbcTemplate.queryForInt(selectSql, b.getBookid())== 0) {
				String insertSql = "insert into bookmarker (markerid,uid,bookid,cfi,curr_chapter,title,content,create_time) values(?,?,?,?,?,?,?,?)";
				System.out.println(insertSql);
				jdbcTemplate.update(insertSql, b.getMarkerid().toString(), b.getUid(), b.getBookid(), b.getCfi(),
						b.getCurr_chapter(), b.getTitle(), b.getContent(), b.getCreate_time().toString());
			}
		}
		return true;
	}

	/**
	 * 将阅读位置同步到数据库
	 * 
	 * @param list
	 *            阅读位置信息
	 * @return true：成功
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean addReadPosition(final List<ReadPosition> list) {
		String selectSql = "select count(*)as count,update_time from readposition where readPositionid=? and bookid=?  ";
		System.out.println(selectSql);
		for (ReadPosition r : list) {
			Map<String, Object> map = jdbcTemplate.queryForMap(selectSql, r.getReadPositionid(), r.getBookid());
			if (((Long) map.get("count")) > 0) {
				if (compare_date(r.getUpdate_time().toString(), map.get("update_time").toString())) {
					String updateSql = "update readposition set cfi=? , curr_chapter=? , update_time=? where readPositionid=?";
					System.out.println(updateSql);
					jdbcTemplate.update(updateSql, r.getCfi(), r.getCurr_chapter(), r.getUpdate_time(),
							r.getReadPositionid());
				}
			} else {
				String insertSql = "insert into readposition (readPositionid,uid,bookid,cfi,curr_chapter,update_time) values(?,?,?,?,?,?)";
				System.out.println(insertSql);
				jdbcTemplate.update(insertSql, r.getReadPositionid(), r.getUid(), r.getBookid(), r.getCfi(),
						r.getCurr_chapter(), r.getUpdate_time().toString());
			}
		}
		return true;
	}

	private boolean compare_date(String date1, String date2) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
		try {
			Date dt1 = df.parse(date1);
			Date dt2 = df.parse(date2);
			if (dt1.getTime() > dt2.getTime()) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 从数据库获取书签信息
	 * 
	 * @param uid
	 *            用户id
	 * @param bookid
	 *            图书id
	 * @param markids
	 *            本地已有的书签id
	 * @return 书签信息
	 */
	@Transactional(readOnly = false)
	public List<Bookmarker> getBookmarkByNoMarkerids(final int uid, final int bookid, final List<Bookmarker> list) {
		List<Bookmarker> bookmarkerList = new ArrayList<Bookmarker>();
		StringBuilder selectNoMarkeridSql = new StringBuilder("select * from bookmarker where uid=? and bookid=?");
		for (int i = 0; i < list.size(); i++) {
			selectNoMarkeridSql.append(" and markerid!='").append(list.get(i).getMarkerid()).append("'");
		}
		System.out.println(selectNoMarkeridSql);
		// try {
		List<Map<String, Object>> maps = jdbcTemplate.queryForList(selectNoMarkeridSql.toString(), uid, bookid);
		for (Map<String, Object> map : maps) {
			Bookmarker bookmarker = BookmarkerUtil.parseBookmarker(map);
			if (bookmarker != null) {
				bookmarkerList.add(bookmarker);
			}
		}
		// } catch (DataAccessException e) {
		// e.printStackTrace();
		// return new ArrayList<Bookmarker>();
		// }

		return bookmarkerList;

	}

	/**
	 * 根据 "书签id" 删除书签信息
	 * 
	 * @param markerid
	 * @return true：成功，false：失败
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean deleteByMarkerids(final List<Bookmarker> list){
		String selectSql = "select count(*) from bookmarker where markerid=? ";
		System.out.println(selectSql);
		for(Bookmarker b : list){
			int count = jdbcTemplate.queryForInt(selectSql, b.getMarkerid());
			if (count < 1) {
				continue;
			}
			String deleteSql = "delete from bookmarker where markerid=? ";
			System.out.println(deleteSql);
			jdbcTemplate.update(deleteSql, b.getMarkerid());
		}
		return true;
		

	}

	/**
	 * 获取阅读位置信息
	 * @param uid     用户id
	 * @param bookid  图书id
	 * @return 阅读位置信息
	 */
	public List<ReadPosition> getReadPositionByBookid(int uid, int bookid) {
		List<ReadPosition> readPositionList = new ArrayList<ReadPosition>();
		String selectSql = "select * from readposition where uid=? and bookid=? ";
		System.out.println(selectSql);
		try {
			List<Map<String, Object>> maps = jdbcTemplate.queryForList(selectSql.toString(), uid, bookid);
			for (Map<String, Object> map : maps) {
				ReadPosition readPosition = BookmarkerUtil.parseReadPosition(map);
				if (readPosition != null) {
					readPositionList.add(readPosition);
				}
			}
		} catch (DataAccessException e) {
			e.printStackTrace();
			return new ArrayList<ReadPosition>();
		}
		return readPositionList;
	}
}
